x86 mce: move mce quirks into separate files
authorKeir Fraser <keir.fraser@citrix.com>
Fri, 14 Aug 2009 16:09:39 +0000 (17:09 +0100)
committerKeir Fraser <keir.fraser@citrix.com>
Fri, 14 Aug 2009 16:09:39 +0000 (17:09 +0100)
Quirk handling is designed to easily add more quirks when needed
w/o messing around in the normal mce code.

Signed-off-by: Christoph Egger <Christoph.Egger@amd.com>
xen/arch/x86/cpu/mcheck/Makefile
xen/arch/x86/cpu/mcheck/amd_k8.c
xen/arch/x86/cpu/mcheck/mce_amd_quirks.c [new file with mode: 0644]
xen/arch/x86/cpu/mcheck/mce_quirks.h [new file with mode: 0644]

index 5aa637a4e052d525d734fd8aed5308d15457faf3..f2d5695510a89457964195775125e73db12eeda5 100644 (file)
@@ -5,4 +5,5 @@ obj-y += amd_f10.o
 obj-y += mctelem.o
 obj-y += mce.o
 obj-y += mce_intel.o
+obj-y += mce_amd_quirks.o
 obj-y += non-fatal.o
index 0bcd6cb3a6bb644783c20ee4aa8b993ba29fa2d9..6a5859c13c5a26e8f962e123029567cafc383b56 100644 (file)
@@ -67,7 +67,7 @@
 #include <asm/msr.h>
 
 #include "mce.h"
-
+#include "mce_quirks.h"
 
 /* Machine Check Handler for AMD K8 family series */
 static void k8_machine_check(struct cpu_user_regs *regs, long error_code)
@@ -79,31 +79,21 @@ static void k8_machine_check(struct cpu_user_regs *regs, long error_code)
 int amd_k8_mcheck_init(struct cpuinfo_x86 *c)
 {
        uint32_t i;
+       enum mcequirk_amd_flags quirkflag;
 
        /* Check for PPro style MCA; our caller has confirmed MCE support. */
        if (!cpu_has(c, X86_FEATURE_MCA))
                return 0;
 
+       quirkflag = mcequirk_lookup_amd_quirkdata(c);
+
        mce_cap_init();
        x86_mce_vector_register(k8_machine_check);
 
        for (i = 0; i < nr_mce_banks; i++) {
-               switch (i) {
-               case 4: /* Northbridge */
-                       if (c->x86 == 0xf) {
-                               /*
-                                * Enable error reporting of all errors except
-                                * for GART TBL walk error reporting, which
-                                * trips off incorrectly with IOMMU & 3ware &
-                                * Cerberus.
-                                */
-                               wrmsrl(MSR_IA32_MC4_CTL, ~(1ULL << 10));
-                               wrmsrl(MSR_IA32_MC4_STATUS, 0x0ULL);
-                               break;
-                       }
-                       /* fall through */
-
-               default:
+               if (quirkflag == MCEQUIRK_K8_GART && i == 4) {
+                       mcequirk_amd_apply(quirkflag);
+               } else {
                        /* Enable error reporting of all errors */
                        wrmsrl(MSR_IA32_MC0_CTL + 4 * i, 0xffffffffffffffffULL);
                        wrmsrl(MSR_IA32_MC0_STATUS + 4 * i, 0x0ULL);
diff --git a/xen/arch/x86/cpu/mcheck/mce_amd_quirks.c b/xen/arch/x86/cpu/mcheck/mce_amd_quirks.c
new file mode 100644 (file)
index 0000000..2067c7c
--- /dev/null
@@ -0,0 +1,73 @@
+/*
+ * MCA quirks for AMD CPUs
+ * Copyright (c) 2009 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include <asm-x86/msr.h>
+#include <asm-x86/processor.h>
+
+#include "mce_quirks.h"
+
+#define ANY -1
+
+static const struct mce_quirkdata mce_amd_quirks[] = {
+       { 0x6 /* cpu family */, ANY /* all models */, ANY /* all steppings */,
+         MCEQUIRK_K7_BANK0 },
+       { 0xf /* cpu family */, ANY /* all models */, ANY /* all steppings */,
+         MCEQUIRK_K8_GART },
+};
+
+enum mcequirk_amd_flags
+mcequirk_lookup_amd_quirkdata(struct cpuinfo_x86 *c)
+{
+       int i;
+
+       BUG_ON(c->x86_vendor != X86_VENDOR_AMD);
+
+       for (i = 0; i < ARRAY_SIZE(mce_amd_quirks); i++) {
+               if (c->x86 != mce_amd_quirks[i].cpu_family)
+                       continue;
+               if ( (mce_amd_quirks[i].cpu_model != ANY) &&
+                    (mce_amd_quirks[i].cpu_model != c->x86_model) )
+                       continue;
+               if ( (mce_amd_quirks[i].cpu_stepping != ANY) &&
+                    (mce_amd_quirks[i].cpu_stepping != c->x86_mask) )
+                       continue;
+               return mce_amd_quirks[i].quirk;
+       }
+       return 0;
+}
+
+int mcequirk_amd_apply(enum mcequirk_amd_flags flags)
+{
+       switch (flags) {
+       case MCEQUIRK_K7_BANK0:
+               return 1; /* first bank */
+
+       case MCEQUIRK_K8_GART:
+               /*
+                * Enable error reporting for all errors except for GART
+                * TBL walk error reporting, which trips off incorrectly
+                * with AGP GART & 3ware & Cerberus.
+                */
+               wrmsrl(MSR_IA32_MC4_CTL, ~(1ULL << 10));
+               wrmsrl(MSR_IA32_MC4_STATUS, 0ULL);
+               break;
+       }
+
+       return 0;
+}
diff --git a/xen/arch/x86/cpu/mcheck/mce_quirks.h b/xen/arch/x86/cpu/mcheck/mce_quirks.h
new file mode 100644 (file)
index 0000000..055ba3b
--- /dev/null
@@ -0,0 +1,54 @@
+/* * MCA quirks
+ * Copyright (c) 2009 Advanced Micro Devices, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#ifndef _MCE_QUIRK_H
+#define _MCE_QUIRK_H
+
+#include <xen/types.h>
+
+struct mce_quirkdata {
+       int32_t cpu_family;
+       int16_t cpu_model;
+       int16_t cpu_stepping;
+       uint32_t quirk;
+};
+
+/* use a binary flag if multiple quirks apply
+ * to one CPU family/model
+ */
+
+enum mcequirk_amd_flags {
+       MCEQUIRK_K7_BANK0 = 0x1,
+       MCEQUIRK_K8_GART = 0x2,
+};
+
+enum mcequirk_intel_flags {
+       MCEQUIRK_DUMMY = 0x1, /* nothing known yet */
+};
+
+enum mcequirk_amd_flags
+mcequirk_lookup_amd_quirkdata(struct cpuinfo_x86 *c);
+
+int mcequirk_amd_apply(enum mcequirk_amd_flags flags);
+
+enum mcequirk_intel_flags
+mcequirk_lookup_intel_quirkdata(struct cpuinfo_x86 *c);
+
+int mcequirk_intel_apply(enum mcequirk_intel_flags flags);
+
+#endif /* _MCE_QUIRK_H */